<template>
    <div class="container"  @contextmenu.prevent="onContextmenu">
      <div id="terminal-container"></div>
    </div>
</template>
<script>
import { SerialPort } from 'serialport'
import {Terminal} from 'xterm'
import { FitAddon } from 'xterm-addon-fit';
import "xterm/lib/xterm.js";
import 'xterm/css/xterm.css'
export default {
  name: 'HelloWorld',
  data(){
    return{
      cols:100,
      rows:40,
      serialPort:'',
      term:'',
      show:false,
      baud:9600,
      isconnect:false,
      ports:[]
    }
  },
  mounted(){
    this.updatePort()
    let that=this;
    this.rows = document.querySelector(".container").offsetHeight / 16 - 6;
    this.cols = document.querySelector(".container").offsetWidth / 14;
    this.initTerminal();
    this.timer=setInterval(()=>{
      that.updatePort()
    },2000);
  },
  methods:{
    parseFunc(){
      if(!this.isconnect){
        this.term.writeln("请先连接串口")
        return
      }
      let _this=this
      navigator.clipboard.readText().then(
      clipText => _this.serialPort.write(clipText));
    },
    async updatePort(){
      let that=this
      await SerialPort.list().then(ports=>{
        that.ports=[];
        for(let i in ports){
          that.ports.push({label:ports[i].path,onClick:()=>{that.selectCOM(ports[i].path)}})
        }
      })
    },
    onContextmenu(event) {
      let that=this;
      this.$contextmenu({
        items: [
          {
            label:"选择串口",
            children:that.ports
          },
          {
            label:"选择波特率",
            children:[
              {label:"9600",onClick:()=>{that.selectBaud(9600)}},
              {label:"115200",onClick:()=>{that.selectBaud(115200)}},
              {label:"19200",onClick:()=>{that.selectBaud(19200)}},
              {label:"57600",onClick:()=>{that.selectBaud(57600)}}
            ]
          },
          {
            label:"粘贴",
            onClick:()=>{
              this.parseFunc()
            }
          }
        ],
        event,
        customClass: "class-a",
        zIndex: 3,
        minWidth: 150
      });
      return false;
    },
    selectCOM(serialname){
      if(this.isconnect){
        this.serialPort.close()
      }
      this.connectSerial(serialname,this.baud)
    },
    selectBaud(baud){
      this.baud=baud;
      if(this.isconnect){
        this.serialPort.update({baudRate:baud})
        this.term.writeln("波特率已切换");
      }
    },
    initTerminal(){
      let _this=this;
      let terminalContainer = document.getElementById('terminal-container')
      let term = new Terminal({
      rendererType: "canvas", //渲染类型
      rows: parseInt(this.rows), //行数
      cols: parseInt(this.cols), // 不指定行数，自动回车后光标从下一行开始
      convertEol: true, //启用时，光标将设置为下一行的开头
      //   scrollback: 50, //终端中的回滚量
      disableStdin: false, //是否应禁用输入。
      cursorStyle: "underline", //光标样式
      cursorBlink: true, //光标闪烁
      theme: {
        foreground: "#FFFFFF", //字体
        background: "#002833", //背景色
        cursor: "help", //设置光标
        lineHeight: 16
      }
      });
      term.open(terminalContainer)
      term.onData((data)=>{
        _this.serialPort.write(data)
      })
      term.attachCustomKeyEventHandler(function(ev) {
      if (ev.keyCode == 86 && ev.ctrlKey && ev.type=='keydown') {
        //_this.serialPort.write();
        ev.preventDefault();
        _this.parseFunc();
        return false;
      }
      return true;
      });
      var fitAddon = new FitAddon();
      term.loadAddon(fitAddon);
      fitAddon.fit();
      window.addEventListener("resize", function(){
        fitAddon.fit();
      })
      
      term.focus();
      this.term=term
    },
    connectSerial(serialname,baudRate){
      let _this=this;
      _this.serialPort=new SerialPort({
        path:serialname,
        baudRate: baudRate,
        dataBits: 8,
        autoOpen: false
      })
      _this.serialPort.on('close',()=>{
        _this.term.writeln("串口已断开");
        _this.isconnect=false;
      })
      _this.serialPort.open((err) => {
      if (err) {
        _this.term.writeln("串口"+serialname+"打开失败")
      }else{
      _this.term.writeln("串口"+serialname+"已打开")
      _this.isconnect=true;
      _this.term.focus();
      }});
      _this.serialPort.on('readable', function () {
      _this.term.write(_this.serialPort.read())
      })
    }
}
}
</script>
<style scoped>
.container{
  height: 100%;
  width: 100%;
  background: #002833;
  position: absolute;
  left: 0;
  top: 0;
}
.selectMenu{
  background: blueviolet;
}
</style>
